package main.controller;

import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import com.redfin.sitemapgenerator.ChangeFreq;
import com.redfin.sitemapgenerator.WebSitemapGenerator;
import com.redfin.sitemapgenerator.WebSitemapUrl;
import main.CatlogHelper;
import main.GlobalConfig;
import main.Logman;
import main.database.DatabaseMan;
import org.bson.Document;
import org.bson.conversions.Bson;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.Writer;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

import static com.mongodb.client.model.Filters.and;
import static com.mongodb.client.model.Filters.eq;

@Controller
public class SitemapPageController {
    @GetMapping("/sitemap.xml")
    public void createSiteMap(HttpServletResponse response) throws IOException {
        response.setContentType(MediaType.APPLICATION_XML_VALUE);
        Writer writer = response.getWriter();
        writer.append(createSiteMapContent());
    }

    private String createSiteMapContent() {
        String baseUrl = GlobalConfig.siteUrl;
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        WebSitemapGenerator wsg = null;
        try {
            wsg = new WebSitemapGenerator(baseUrl);
            // 首页 url
            WebSitemapUrl url = new WebSitemapUrl.Options(baseUrl)
                    .lastMod(dateTimeFormatter.format(LocalDateTime.now())).priority(1.0).changeFreq(ChangeFreq.DAILY).build();
            wsg.addUrl(url);

            WebSitemapUrl tmpUrl;
            // articles
            MongoCollection<Document> collection = DatabaseMan.Instance().GetCollection(GlobalConfig.collectionNameOfArticle);
            FindIterable<Document> findIterable = collection.find();
            MongoCursor<Document> cursor = findIterable.iterator();

            while(cursor.hasNext()) {
                tmpUrl = new WebSitemapUrl.Options(baseUrl + "/fiction/" + cursor.next().get("_id").toString())
                        .lastMod(dateTimeFormatter.format(LocalDateTime.now())).priority(0.9).changeFreq(ChangeFreq.DAILY).build();
                wsg.addUrl(tmpUrl);
            }
            cursor.close();

            // authors
            collection = DatabaseMan.Instance().GetCollection(GlobalConfig.collectionNameOfAuthor);
            findIterable = collection.find();
            cursor = findIterable.iterator();

            while(cursor.hasNext()) {
                tmpUrl = new WebSitemapUrl.Options(baseUrl + "/author/" + cursor.next().get("_id").toString())
                        .lastMod(dateTimeFormatter.format(LocalDateTime.now())).priority(0.9).changeFreq(ChangeFreq.MONTHLY).build();
                wsg.addUrl(tmpUrl);
            }
            cursor.close();

            // rankpage
            collection = DatabaseMan.Instance().GetCollection(GlobalConfig.collectionNameOfRootCatlog);
            findIterable = collection.find();
            cursor = findIterable.iterator();
            List<String> catlogList = new ArrayList<>();
            catlogList.add("zonghe");
            while(cursor.hasNext()) {
                String uri = cursor.next().get("uri").toString();
                catlogList.add(uri.substring(1, uri.length()));
            }
            cursor.close();
            for(int i = 0; i < catlogList.size(); ++i) {
                String type = catlogList.get(i);
                long count = countTypeOfCatlog(type);
                for (int index = 0; index < count; ++index) {
                    tmpUrl = new WebSitemapUrl.Options(baseUrl + "/rankpage/" + type + "/" + index)
                            .lastMod(dateTimeFormatter.format(LocalDateTime.now())).priority(0.9).changeFreq(ChangeFreq.DAILY).build();
                    wsg.addUrl(tmpUrl);
                }
            }

            // article repository
            tmpUrl = new WebSitemapUrl.Options(baseUrl + "/articlerepository")
                    .lastMod(dateTimeFormatter.format(LocalDateTime.now())).priority(0.9).changeFreq(ChangeFreq.DAILY).build();
            wsg.addUrl(tmpUrl);

            // author repository
            tmpUrl = new WebSitemapUrl.Options(baseUrl + "/authorrepository")
                    .lastMod(dateTimeFormatter.format(LocalDateTime.now())).priority(0.9).changeFreq(ChangeFreq.DAILY).build();
            wsg.addUrl(tmpUrl);

            // articlecollected
            tmpUrl = new WebSitemapUrl.Options(baseUrl + "/articlecollected")
                    .lastMod(dateTimeFormatter.format(LocalDateTime.now())).priority(0.9).changeFreq(ChangeFreq.DAILY).build();
            wsg.addUrl(tmpUrl);

            // authorcollected
            tmpUrl = new WebSitemapUrl.Options(baseUrl + "/authorcollected")
                    .lastMod(dateTimeFormatter.format(LocalDateTime.now())).priority(0.9).changeFreq(ChangeFreq.DAILY).build();
            wsg.addUrl(tmpUrl);

        } catch (Exception e) {
            Logman.error("create sitemap xml error:" + e.toString());
        }
        return String.join("", wsg.writeAsStrings());
    }

    private long countTypeOfCatlog(String type) {
        MongoCollection<Document> collection = DatabaseMan.Instance().GetCollection(GlobalConfig.collectionNameOfArticle);
        Bson filter = CatlogHelper.typeToFilter(type);
        filter = and(filter, eq("finished", true));

        //总共数量
        long count = collection.countDocuments(filter);
        if (type.equals("zonghe") && count > 100) {
            count = 100;
        }
        long totalPage = count / GlobalConfig.itemPerRankPage;
        if (count % GlobalConfig.itemPerRankPage != 0) {
            totalPage++;
        }
        return totalPage;
    }
}
